using System;
using System.Collections.Generic;
using System.Linq;

namespace Super
{
	[Serializable]
	public class ExcelDictionary<T1, TResult> where TResult : new()
	{
		public SerializeDict<T1, TResult> dic = new SerializeDict<T1, TResult>();

		public TResult Find(T1 key)
		{
			if (dic.ContainsKey(key)) return dic[key];
			return default(TResult);
		}

		public List<TResult> GetAllData()
		{
			List<TResult> list = new List<TResult>();
			foreach (var item in dic.Values)
			{
				list.Add(item);
			}
			return list;
		}

		public void Add(TResult data, string[] keys)
		{
			System.Type TResult_Type = typeof(TResult);
			var TResult_Key_Value = (T1)TResult_Type.GetField(keys[0]).GetValue(data);

			bool isValid = (int)TResult_Type.GetField("valid").GetValue(data) == 1;

			if (isValid)
				dic.Add(TResult_Key_Value, data);
		}

		public void Clear()
		{
			dic.Clear();
		}
	}

	[Serializable]
	public class ExcelDictionary<T1, T2, TResult> where TResult : new()
	{
		public SerializeDict<T1, ExcelDictionary<T2, TResult>> dic = new SerializeDict<T1, ExcelDictionary<T2, TResult>>();
		public TResult Find(T1 key1, T2 key2)
		{
			if (dic.ContainsKey(key1)) return dic[key1].Find(key2);
			return default(TResult);
		}

		public ExcelDictionary<T2, TResult> Find(T1 key)
		{
			if (dic.ContainsKey(key)) return dic[key];
			return new ExcelDictionary<T2, TResult>();
		}

		public List<TResult> GetAllData()
		{
			List<TResult> list = new List<TResult>();
			foreach (var item in dic.Values)
			{
				List<TResult> itemAllData = item.GetAllData();
				list.AddRange(itemAllData);
			}
			return list;
		}

		public void Add(TResult data, string[] keys)
		{
			System.Type TResult_Type = typeof(TResult);
			var TResult_Key_Value = (T1)TResult_Type.GetField(keys[0]).GetValue(data);
			var value = Find(TResult_Key_Value);
			value.Add(data, keys.Skip(1).ToArray());

			if (!dic.ContainsKey(TResult_Key_Value))
			{
				dic.Add(TResult_Key_Value, value);
			}
		}

		public void Clear()
		{
			dic.Clear();
		}
	}

	[Serializable]
	public class ExcelDictionary<T1, T2, T3, TResult> where TResult : new()
	{
		public SerializeDict<T1, ExcelDictionary<T2, T3, TResult>> dic = new SerializeDict<T1, ExcelDictionary<T2, T3, TResult>>();

		public TResult Find(T1 key1, T2 key2, T3 key3)
		{
			if (dic.ContainsKey(key1)) return dic[key1].Find(key2, key3);
			return default(TResult);
		}

		public ExcelDictionary<T3, TResult> Find(T1 key1, T2 key2)
		{
			if (dic.ContainsKey(key1)) return dic[key1].Find(key2);
			return new ExcelDictionary<T3, TResult>();
		}

		public ExcelDictionary<T2, T3, TResult> Find(T1 key)
		{
			if (dic.ContainsKey(key)) return dic[key];
			return new ExcelDictionary<T2, T3, TResult>();
		}

		public List<TResult> GetAllData()
		{
			List<TResult> list = new List<TResult>();
			foreach (var item in dic.Values)
			{
				List<TResult> itemAllData = item.GetAllData();
				list.AddRange(itemAllData);
			}
			return list;
		}

		public void Add(TResult data, string[] keys)
		{
			System.Type TResult_Type = typeof(TResult);
			var TResult_Key_Value = (T1)TResult_Type.GetField(keys[0]).GetValue(data);
			var value = Find(TResult_Key_Value);
			value.Add(data, keys.Skip(1).ToArray());

			if (!dic.ContainsKey(TResult_Key_Value))
			{
				dic.Add(TResult_Key_Value, value);
			}
		}

		public void Clear()
		{
			dic.Clear();
		}
	}

	[Serializable]
	public class ExcelDictionary<T1, T2, T3, T4, TResult> where TResult : new()
	{
		public SerializeDict<T1, ExcelDictionary<T2, T3, T4, TResult>> dic = new SerializeDict<T1, ExcelDictionary<T2, T3, T4, TResult>>();

		public TResult Find(T1 key1, T2 key2, T3 key3, T4 key4)
		{
			if (dic.ContainsKey(key1)) return dic[key1].Find(key2, key3, key4);
			return default(TResult);
		}

		public ExcelDictionary<T4, TResult> Find(T1 key1, T2 key2, T3 key3)
		{
			if (dic.ContainsKey(key1)) return dic[key1].Find(key2, key3);
			return new ExcelDictionary<T4, TResult>();
		}

		public ExcelDictionary<T3, T4, TResult> Find(T1 key1, T2 key2)
		{
			if (dic.ContainsKey(key1)) return dic[key1].Find(key2);
			return new ExcelDictionary<T3, T4, TResult>();
		}

		public ExcelDictionary<T2, T3, T4, TResult> Find(T1 key1)
		{
			if (dic.ContainsKey(key1)) return dic[key1];
			return new ExcelDictionary<T2, T3, T4, TResult>();
		}

		public List<TResult> GetAllData()
		{
			List<TResult> list = new List<TResult>();
			foreach (var item in dic.Values)
			{
				List<TResult> itemAllData = item.GetAllData();
				list.AddRange(itemAllData);
			}
			return list;
		}

		public void Add(TResult data, string[] keys)
		{
			System.Type TResult_Type = typeof(TResult);
			var TResult_Key_Value = (T1)TResult_Type.GetField(keys[0]).GetValue(data);
			var value = Find(TResult_Key_Value);
			value.Add(data, keys.Skip(1).ToArray());

			if (!dic.ContainsKey(TResult_Key_Value))
			{
				dic.Add(TResult_Key_Value, value);
			}
		}

		public void Clear()
		{
			dic.Clear();
		}
	}
}
